;; Copying and distribution of this file, with or without
;; modification, are permitted in any medium without royalty provided
;; the copyright notice and this notice are preserved.  This file is
;; offered as-is, without any warranty.


;;; Dit programma simuleert de simpele Markovketen voor namen met de
;;; 'e' en 'n' die als voorbeeld wordt gebruikt in het verslag. Elke
;;; staat wordt gesimuleerd door een functie die de desbetreffende
;;; letter print en daarna gebaseerd op kans verder gaat naar de
;;; volgende staat.
;;;
;;; Dit programma is geschreven in Scheme, omdat dat een handige taal
;;; is om snel en elegant een prototype in uit te drukken. Alles wat
;;; na een ; komt is in Scheme een commentaar en wordt dus niet door
;;; gebruikt tijdens het uitvoeren van het programma. De functie
;;; random:uniform wordt gebruikt om een willekeurig nummer tussen de
;;; 0 en 1 te krijgen. De functie display drukt de gegeven letter af
;;; en newline eindigt de line, ongeveer hetzelfde alsof je enter
;;; indrukt op je toetsenbord.

;;; De BEGIN toestand (dit kon niet begin worden genoemd omdat dat zou
;;; conflicteren met een naam die al in Scheme voorkomt)
(define (start)
  (if (< (random:uniform) 0.6) ; Als het willekeurige nummer kleiner
                               ; is dan 0.6
      (e)                      ; Ga dan naar de 'e' toestand
      (n)))                    ; Zo niet, ga dan naar de 'n' toestand

;;; De 'e' toestand
(define (e)
  (display "e")                    ; Laat de letter 'e' zien
  (let ((rand (random:uniform)))   ; Verbindt een willekeurig nummer
                                   ; aan de naam "rand"
    (cond ((< rand 0.4) (e))       ; Als het willekeurige nummer
                                   ; kleiner is dan 0.4 ga dan naar 'e'
          ((< rand 0.9) (n))       ; Anders als het willekeurige
                                   ; nummer kleiner is dan 0.9 ga naar
                                   ; 'n'
          (else         (eind))))) ; Als die beiden niet zo waren ga
                                   ; dan naar EIND

;;; De 'n' toestand
(define (n)
  (display "n")                    ; Laat de letter 'n' zien
  (let ((rand (random:uniform)))   ; Verbindt een willekeurig nummer
                                   ; aan de naam "rand"
    (cond ((< rand 0.3) (n))       ; Als het willekeurige nummer
                                   ; kleiner is dan 0.3 ga dan naar 'n'
          ((< rand 0.7) (e))       ; Anders als het willekeurige
                                   ; nummer kleiner is dan 0.7 ga naar
                                   ; 'e'
          (else         (eind))))) ; Als die beiden niet zo waren ga
                                   ; dan naar EIND

;;; De EIND toestand
(define (eind)
  (newline))                       ; Beeindig de naam met een 'enter'
                                   ; en doe verder niks meer.

;;; De zogenaamde "random-state" van het systeem moet eerst worden
;;; gevoedt met een "seed", want anders geeft het programma elke keer
;;; dezelfde naam.
(set! *random-state* (random-state-from-platform))

;;; Hier wordt de Markovketen gestart door in de BEGIN toestand te beginnen.
(start)
